import logging
import os

from django.conf import settings
from django.db.models import Q
from django.urls import reverse
from django.utils import timezone
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from account.models import User
from common.tools.common_tools import gen_id_number
from common.tools.money_cast import transforms_int
from common.views import get_obj
from common.wx.config import WxPayConf_pub, WxPayConf_service, WxPayConf_shop
from common.wx.pay import WxApi_pub, UnifiedOrder_pub
from groupshopping.models import ShoppingMem, ShoppingGroup, ShoppingModel, GroupShopping
from kill.models import KillProduct, KillRecord
from open.models import WxPublicMapShop, WxPayInfo
from order.models import Order, OrderProduct, Receiver, RefundOrder
from product.models import Product
from wehelp.models import KanjiaInfo, KanJiaUserMaster

logger = logging.getLogger('qixiaobao')


class OrderProductCreateView(APIView):
    """
    生成商品订单
    接收的数据类型为：
    {
        "id":商品id
        "number":商品数量
        "amount":商品总价
    }
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'id', 'number', 'amount', 'name', 'phone'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})
        product_id = request.data['id']
        product_number = transforms_int(request.data['number'], 1)
        comment = request.data.get('comment', '')
        amount = transforms_int(request.data['amount'])
        name = request.data['name']
        phone = request.data['phone']
        # address = request.data['address']
        product_amount = 0
        if not name:
            return Response({'status': 1, 'detail': '姓名未填写！'})
        if not phone:
            return Response({'status': 1, 'detail': '手机未填写！'})
        try:
            product = Product.objects.get(id=product_id, shelve=True, status=Product.STATUS_VALID)
        except Product.DoesNotExist:
            return Response({'status': 1, 'detail': '购买的产品不存在或未上架'})

        if not product.inventory > 0:
            return Response({'status': 1, 'detail': '库存不足，请重新下单'})
        product_amount += product.price_discount * product_number
        if product_amount != amount:
            return Response({'status': 1, 'detail': '产品价格发生变化，请重新下单'})

        order_id = str(request.user.id) + timezone.now().strftime('%Y%m%d%H%M%S') + str(
            gen_id_number(4))
        receiver, receiver_flag = Receiver.objects.get_or_create(user=request.user, name=name,  # address=address,
                                                                 phone=phone)
        order = Order.objects.create(id=order_id,
                                     shop=product.shop,
                                     user=request.user,
                                     order_type=Order.ORDER_PRODUCT,
                                     misc_desc='商品订单',
                                     receiver=receiver,
                                     pay_type=product.shop.user.pay_type,
                                     amount=product_amount,
                                     state=Order.STATE_WAIT_PAY,
                                     comment=comment,
                                     status=Order.STATUS_VALID)

        OrderProduct.objects.create(order=order,
                                    content_object=product,
                                    price=product.price_discount,
                                    number=product_number,
                                    amount=product_amount,
                                    status=OrderProduct.STATUS_VALID)
        if order.shop.user.pay_type in [User.PAY_XIAODU, User.SELF_PUB, User.PAY_WX_SERVICE]:
            # 小嘟科技，自己公众号， 微信服务商
            data = {'status': 0, 'detail': {'order': order_id, 'amount':product_amount, 'pay': 'self'}}
        else:  # 暂时放在这里，待修改
            # domain_url = 'http://%s.yjb.xuemei99.com' % order.shop.id
            # next_url = quote(
            #     '%s%s' % (domain_url, reverse('m_v3:order_success', args=[order_id]) + '?shop=%s' % order.shop.id),
            #     safe='')
            # cancel_url = 'back'
            data = {'status': 0, 'detail': {'order': order_id,
                                            'pay': 'xd',
                                            # 'pay_url': '%s%s?next=%s&cancel=%s' % ('http://yjb.xuemei99.com',
                                            #                                        reverse('mobile_order_pay_proxy',
                                            #                                                args=[order_id]),
                                            #                                        next_url, cancel_url)
                                            }
                    }
        return Response(data)


class OrderKillProductCreateView(APIView):
    """
    生成秒杀订单
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'id', 'amount', 'name', 'phone'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})
        product_id = request.data['id']
        product_number = transforms_int(request.data.get('number', 1), 1)
        comment = request.data.get('comment', '')
        amount = transforms_int(request.data['amount'])
        name = request.data['name']
        phone = request.data['phone']
        # address = request.data['address']
        product_amount = 0
        if not name:
            return Response({'status': 1, 'detail': '姓名未填写！'})
        if not phone:
            return Response({'status': 1, 'detail': '手机未填写！'})
        try:
            kill_product = KillProduct.objects.get(id=product_id, shelve=True, status=Product.STATUS_VALID)
        except KillProduct.DoesNotExist:
            return Response({'status': 1, 'detail': '购买的产品不存在或未上架'})

        if not kill_product.get_inventory_status():
            return Response({'status': 1, 'detail': '库存不足，请重新下单'})
        product_amount += kill_product.price_discount * product_number
        if product_amount != amount:
            return Response({'status': 1, 'detail': '产品价格发生变化，请重新下单'})

        has_join = KillRecord.objects.filter(
            info=kill_product,
            status=KillRecord.STATUS_VALID
        ).filter(Q(user=request.user) | Q(phone=phone)).exists()

        if has_join:
            return Response({'status': 1, 'detail': '已参加过抢购，请勿重复下单'})

        order_id = str(request.user.id) + timezone.now().strftime('%Y%m%d%H%M%S') + str(
            gen_id_number(4))
        receiver, receiver_flag = Receiver.objects.get_or_create(user=request.user, name=name,  # address=address,
                                                                 phone=phone)
        order = Order.objects.create(id=order_id,
                                     shop=kill_product.shop,
                                     user=request.user,
                                     order_type=Order.ORDER_PRODUCT,
                                     misc_desc='商品订单',
                                     receiver=receiver,
                                     pay_type=kill_product.shop.user.pay_type,
                                     amount=product_amount,
                                     state=Order.STATE_WAIT_PAY,
                                     comment=comment,
                                     status=Order.STATUS_VALID)

        OrderProduct.objects.create(order=order,
                                    content_object=kill_product,
                                    price=kill_product.price_discount,
                                    number=product_number,
                                    amount=product_amount,
                                    status=OrderProduct.STATUS_VALID)
        if order.shop.user.pay_type in [User.PAY_XIAODU, User.SELF_PUB, User.PAY_WX_SERVICE]:
            # 小嘟科技，自己公众号， 微信服务商
            data = {'status': 0, 'detail': {'order': order_id, 'amount':product_amount, 'pay': 'self'}}
        else:  # 暂时放在这里，待修改
            # domain_url = 'http://%s.yjb.xuemei99.com' % order.shop.id
            # next_url = quote(
            #     '%s%s' % (domain_url, reverse('m_v3:order_success', args=[order_id]) + '?shop=%s' % order.shop.id),
            #     safe='')
            # cancel_url = 'back'
            data = {'status': 0, 'detail': {'order': order_id,
                                            'pay': 'xd',
                                            # 'pay_url': '%s%s?next=%s&cancel=%s' % ('http://yjb.xuemei99.com',
                                            #                                        reverse('mobile_order_pay_proxy',
                                            #                                                args=[order_id]),
                                            #                                        next_url, cancel_url)
                                            }
                    }
        return Response(data)


class OrderKanjiaCreateView(APIView):
    """
    生成砍价订单d
    接收的数据类型为：
    {
        "id":商品id列表字符串
        "number":商品数量列表字符串
        "amount":商品总价
    }
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'id', 'number', 'amount'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})
        product_id = request.data['id']
        product_number = transforms_int(request.data['number'], 1)
        comment = request.data.get('comment', '')
        amount = transforms_int(request.data['amount'])
        # address = request.data.get('address', '')
        product_amount = 0

        try:
            product = KanjiaInfo.objects.get(id=product_id, shelve=True, status=KanjiaInfo.STATUS_VALID)
        except KanjiaInfo.DoesNotExist:
            return Response({'status': 1, 'detail': '购买的产品不存在或未上架'})

        if not product.has_start():
            return Response({'status': 1, 'detail': '活动还未开始，请耐心等待'})
        elif product.has_end():
            return Response({'status': 1, 'detail': '活动已结束'})
        elif not product.get_inventory > 0:
            return Response({'status': 1, 'detail': '库存不足，请重新下单'})
        product_amount += product.price_discount * product_number
        if product_amount != amount:
            return Response({'status': 1, 'detail': '产品价格发生变化，请重新下单'})

        try:
            master = KanJiaUserMaster.objects.get(user=request.user,
                                                  info=product,
                                                  real_price=product.price_discount,
                                                  status=KanJiaUserMaster.STATUS_VALID)
        except KanJiaUserMaster.DoesNotExist:
            return Response({'status': 1, 'detail': '支付条件检查失败'})

        if master.order and not master.refund and master.order.state != Order.STATE_WAIT_PAY:
            return Response({'status': 1, 'detail': '您已支付过此砍价订单'})

        superior = None
        if master.superior:
            superior = master.superior
        product.save()

        order_id = str(request.user.id) + timezone.now().strftime('%Y%m%d%H%M%S') + str(
            gen_id_number(4))
        receiver, receiver_flag = Receiver.objects.get_or_create(user=request.user, name=master.name,
                                                                 phone=master.phone)
        order = Order.objects.create(id=order_id,
                                     shop=product.shop,
                                     user=request.user,
                                     superior=superior,
                                     order_type=Order.ORDER_KANJIA,
                                     misc_desc='砍价订单',
                                     receiver=receiver,
                                     pay_type=product.shop.user.pay_type,
                                     amount=product_amount,
                                     state=Order.STATE_WAIT_PAY,
                                     comment=comment,
                                     status=Order.STATUS_VALID)

        OrderProduct.objects.create(order=order,
                                    content_object=product,
                                    price=product.price_discount,
                                    number=product_number,
                                    amount=product_amount,
                                    status=OrderProduct.STATUS_VALID)
        master.order = order
        if master.refund:
            master.refund = None
        master.save()
        if order.shop.user.pay_type in [User.PAY_XIAODU, User.SELF_PUB, User.PAY_WX_SERVICE]:  # 小嘟科技，自己公众号， 微信服务商
            data = {'status': 0, 'detail': {'order': order_id, 'pay': 'self'}}
        else:  # 暂时放在这里，待修改
            # domain_url = 'http://%s.yjb.xuemei99.com' % order.shop.id
            # next_url = quote(
            #     '%s%s' % (domain_url, reverse('m_v3:order_success', args=[order_id]) + '?shop=%s' % order.shop.id),
            #     safe='')
            # cancel_url = 'back'
            data = {'status': 0, 'detail': {'order': order_id,
                                            'pay': 'xd',
                                            # 'pay_url': '%s%s?next=%s&cancel=%s' % ('http://yjb.xuemei99.com',
                                            #                                        reverse('mobile_order_pay_proxy',
                                            #                                                args=[order_id]),
                                            #                                        next_url, cancel_url)
                                            }
                    }
        return Response(data)


class OrderGroupShoppingCreateView(APIView):
    """
    生成团购订单
    接收的数据类型为：
    {
        "type":参加类型
        "type"：拼团类型
        "model_number"：团购人数
        "model_price"：团购价格
        "info_id"：团购活动ID
        "name"：姓名
        "phone"：手机
    }
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        logger.debug('OrderGroupShoppingCreateView:request.data')
        logger.debug(request.data)
        if not {'type', 'name', 'phone'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})

        data = request.data
        name = data.get('name', '')
        phone = data.get('phone', '').strip()
        if not name:
            return Response({'status': 1, 'detail': '请输入姓名'})
        if len(phone) != 11:
            return Response({'status': 1, 'detail': '手机号格式错误'})

        tuanshopping_type = transforms_int(data['type'])
        if tuanshopping_type == Order.ORDER_TUANSHOPPING_MASTER:
            model_number = data['model_number']
            model_price = data['model_price']
            try:
                shopping_model = ShoppingModel.objects.get(number=model_number, price=model_price,
                                                           status=ShoppingModel.STATUS_VALID,
                                                           info_id=data['info_id']
                                                           )
            except ShoppingModel.DoesNotExist:
                return Response({'status': 1, 'detail': u'拼团模式不存在'})
        else:
            if data.get('group'):
                group_id = data['group']
            else:
                group_id = 12121212
        try:
            group_shopping = GroupShopping.objects.get(id=data['info_id'],
                                                       status=ShoppingModel.STATUS_VALID)
        except GroupShopping.DoesNotExist:
            return Response({'status': 1, 'detail': u'活动不存在'})

        if not group_shopping.shelve:
            return Response({'status': 1, 'detail': u'活动未上架'})

        if group_shopping.start_time > timezone.now():
            return Response({'status': 1, 'detail': u'活动未开始'})

        if group_shopping.end_time < timezone.now():
            return Response({'status': 1, 'detail': u'活动已截止'})

        has_join = ShoppingMem.objects.filter(
            info=group_shopping,
            group__group_state__in=[ShoppingGroup.GROUP_DOING, ShoppingGroup.GROUP_SUCCESS],
            group__status=ShoppingGroup.STATUS_VALID,
            status=ShoppingMem.STATUS_VALID
        ).filter(Q(user=request.user) | Q(phone=phone)) \
            .exclude(order=None).exclude(refund__state__in=[RefundOrder.STATE_REFUNDING,
                                                            RefundOrder.STATE_REFUNDED,
                                                            RefundOrder.STATE_SYSTEM_REFUNDING,
                                                            RefundOrder.STATE_SYSTEM_REFUNDED]).exists()

        if has_join:
            return Response({'status': 1, 'detail': '已经参加过该团购活动'})
        if not group_shopping.get_inventory_status():
            return Response({'status': 1, 'detail': '活动已满'})
        if tuanshopping_type not in (Order.ORDER_TUANSHOPPING_MASTER, Order.ORDER_TUANSHOPPING_GROUP):
            return Response({'status': 1, 'detail': '状态错误'})
        order_id = str(request.user.id) + timezone.now().strftime('%Y%m%d%H%M%S') + str(gen_id_number(4))
        if not request.user.phone:
            request.user.phone = phone
            request.user.save()

        if tuanshopping_type == Order.ORDER_TUANSHOPPING_MASTER:
            left_number = int(model_number) - 1
            shopping_group = ShoppingGroup.objects.create(info=group_shopping,
                                                          model_number=model_number,
                                                          mdoel_price=model_price,
                                                          master_id=request.user.id,
                                                          left_number=left_number,
                                                          number=1)
            shopping_mem = ShoppingMem.objects.create(shop=group_shopping.shop, info=group_shopping,
                                                      group=shopping_group,
                                                      user=request.user,
                                                      name=name, phone=phone,
                                                      role=ShoppingMem.ROLE_MASTER)
        else:
            try:
                shopping_group = ShoppingGroup.objects.get(id=group_id,
                                                           status=ShoppingGroup.STATUS_VALID)
                if not shopping_group.group_state == ShoppingGroup.GROUP_DOING:
                    return Response({'status': 1, 'detail': '团购状态为%s' % shopping_group.get_group_state_display()})
            except ShoppingGroup.DoesNotExist:
                return Response({'status': 1, 'detail': '团组不存在'})
            # 参团时加锁防止团组人数多入
            join_permission = shopping_group.jurge_by_paying_number()
            if not join_permission:
                return Response({'status': 1, 'detail': '支付中人数受限！'})
            shopping_group.increase_paying_number()

            shopping_mem = ShoppingMem.objects.create(shop=group_shopping.shop, info=group_shopping,
                                                      group=shopping_group,
                                                      user=request.user,
                                                      name=name, phone=phone, role=ShoppingMem.ROLE_GROUPER)
        receiver, receiver_flag = Receiver.objects.get_or_create(user=request.user, name=name, phone=phone,
                                                                 status=Receiver.STATUS_VALID)
        order = Order.objects.create(
            id=order_id,
            shop=group_shopping.shop,
            user=request.user,
            # from_user=from_user,
            # superior=superior,
            misc_desc='团购订单',
            receiver_id=receiver.id,
            order_type=tuanshopping_type,
            pay_type=group_shopping.shop.user.pay_type,
            amount=shopping_group.mdoel_price,
            state=Order.STATE_WAIT_PAY,
            status=Order.STATUS_VALID
        )
        OrderProduct.objects.create(
            order=order,
            content_object=shopping_group,
            price=shopping_group.mdoel_price,
            number=1,
            status=OrderProduct.STATUS_VALID
        )
        shopping_mem.order = order
        shopping_mem.save()
        if order.shop.user.pay_type in [User.SELF_PUB, User.PAY_XIAODU, User.PAY_WX_SERVICE]:
            data = {'status': 0,
                    'detail': {'order': order_id,
                               'pay': 'self',  # 'pay_success_url': url,
                               'pay_url': '',
                               'amount': shopping_group.mdoel_price,
                               'shop': order.shop_id,
                               }
                    }
        else:
            # domain_url = 'http://%s.yjb.xuemei99.com' % order.shop.id
            # next_url = urllib.quote('%s%s' % (domain_url, url), safe='')
            # cancel_url = 'back'
            data = {'status': 0, 'detail': {'order': order_id,
                                            'pay': 'type_no',
                                            # 'pay_url': '%s%s?next=%s&cancel=%s' % ('http://yjb.xuemei99.com',
                                            #                                        reverse('mobile_order_pay_proxy',
                                            #                                                args=[order_id]),
                                            #                                        next_url, cancel_url)
                                            }
                    }
        return Response(data)


# 支付接口

class WxPayForProductView(APIView):
    """
    商品支付请求
    接收的数据类型为：
    {
        "order":订单号，
        "channel":渠道，APP/JSAPI
        "amount":总价
        "openid":微信openid
    }
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'order', 'channel', 'amount', 'openid'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})

        order_id = request.data['order']
        channel = request.data.get('channel', 'APP')
        order_amount = transforms_int(request.data['amount'], 0)
        openid = request.data.get('openid', None)

        ip = request.META.get('REMOTE_ADDR', '127.0.0.1')
        amount = 0

        order = get_obj(Order, id=order_id, user=request.user, state=Order.STATE_WAIT_PAY, status=Order.STATUS_VALID)
        if not order:
            return Response({'status': 2, 'detail': '待支付订单不存在'})

        if not hasattr(order.shop, 'public_shop'):  # 未设置 公众号_店铺 映射信息
            return Response({'status': 23, 'detail': '支付出错，错误码23'})

        # 判断商品价格
        order_product_list = OrderProduct.objects.filter(order_id=order_id, status=OrderProduct.STATUS_VALID)
        for op in order_product_list:
            if not op.type == OrderProduct.OP_GIFT and op.content_object:
                product = op.content_object
                if isinstance(product, Product):
                    if product.status == Product.STATUS_VALID:
                        if op.price == product.price_discount:
                            amount += product.price_discount * op.number
                        else:
                            return Response({'status': 3, 'detail': '商品%s价格已发生了变化，请重新下单' % product.title})
                    else:
                        return Response({'status': 4, 'detail': '商品%s已发生了变化，请重新下单' % op.title})
                else:
                    return Response({'status': 10, 'detail': '活动类型错误'})

        if not amount == order_amount:
            return Response({'status': 5, 'detail': '商品总价已发生了变化，请重新下单'})

        flag, result = wx_pay_prepare(order, order.shop_id, openid, amount, ip, 'product')

        return Response({'status': flag, 'detail': result})


class WxPayForKillProductView(APIView):
    """
    秒杀支付请求
    接收的数据类型为：
    {
        "order":订单号，
        "channel":渠道，APP/JSAPI
        "amount":总价
        "openid":微信openid
    }
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'order', 'channel', 'amount', 'openid'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})

        order_id = request.data['order']
        channel = request.data.get('channel', 'APP')
        order_amount = transforms_int(request.data['amount'], 0)
        openid = request.data.get('openid', None)

        ip = request.META.get('REMOTE_ADDR', '127.0.0.1')
        amount = 0

        order = get_obj(Order, id=order_id, user=request.user, state=Order.STATE_WAIT_PAY, status=Order.STATUS_VALID)
        if not order:
            return Response({'status': 2, 'detail': '待支付订单不存在'})

        if not hasattr(order.shop, 'public_shop'):  # 未设置 公众号_店铺 映射信息
            return Response({'status': 23, 'detail': '支付出错，错误码23'})

        # 判断商品价格
        order_product_list = OrderProduct.objects.filter(order_id=order_id, status=OrderProduct.STATUS_VALID)
        for op in order_product_list:
            if not op.type == OrderProduct.OP_GIFT and op.content_object:
                product = op.content_object
                if isinstance(product, KillProduct):
                    if product.status == KillProduct.STATUS_VALID:
                        if op.price == product.price_discount:
                            amount += product.price_discount * op.number
                        else:
                            return Response({'status': 3, 'detail': '活动%s价格已发生了变化，请重新下单' % product.title})
                    else:
                        return Response({'status': 4, 'detail': '活动%s已发生了变化，请重新下单' % op.title})
                else:
                    return Response({'status': 10, 'detail': '活动类型错误'})

        if not amount == order_amount:
            return Response({'status': 5, 'detail': '活动总价已发生了变化，请重新下单'})

        flag, result = wx_pay_prepare(order, order.shop_id, openid, amount, ip, 'kill')

        return Response({'status': flag, 'detail': result})


class WxPayForKanjiaView(APIView):
    """
    砍价支付请求
    接收的数据类型为：
    {
        "order":订单号，
        "channel":渠道，APP/JSAPI
        "amount":总价
        "openid":微信openid
    }
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'order', 'channel', 'amount', 'openid'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})

        order_id = request.data['order']
        channel = request.data.get('channel', 'APP')
        order_amount = transforms_int(request.data['amount'], 0)
        openid = request.data.get('openid', None)
        logger.debug('砍价支付openid： %s' % openid)

        ip = request.META.get('REMOTE_ADDR', '127.0.0.1')
        amount = 0

        order = get_obj(Order, id=order_id, user=request.user, state=Order.STATE_WAIT_PAY, status=Order.STATUS_VALID)
        if not order:
            return Response({'status': 2, 'detail': '待支付订单不存在'})

        if not hasattr(order.shop, 'public_shop'):  # 未设置 公众号_店铺 映射信息
            return Response({'status': 23, 'detail': '支付出错，错误码23'})

        # 判断商品价格
        order_product_list = OrderProduct.objects.filter(order_id=order_id, status=OrderProduct.STATUS_VALID)
        for op in order_product_list:
            if not op.type == OrderProduct.OP_GIFT and op.content_object:
                product = op.content_object
                if isinstance(product, KanjiaInfo):
                    # 判断是否已经进行砍价支付了，只准进行一次订单的砍价支付
                    if OrderProduct.objects.filter(order__shop=order.shop,
                                                   order__user=request.user,
                                                   order__order_type=Order.ORDER_KANJIA,
                                                   order__state__in=(Order.STATE_SEND, Order.STATE_COMPLETE),
                                                   order__status=Order.STATUS_VALID,
                                                   object_id=op.object_id,
                                                   content_type=op.content_type,
                                                   status=OrderProduct.STATUS_VALID).exists():
                        return Response({'status': 5, 'detail': '您已经支付过该砍价活动，请不要重复支付'})
                    now = timezone.now()
                    if product.start_time > now:
                        return Response({'status': 8, 'detail': '活动还未开始，请耐心等待'})
                    if product.end_time < now:
                        return Response({'status': 9, 'detail': '活动已结束'})
                    if product.status == KanjiaInfo.STATUS_VALID:
                        if op.price == product.price_discount:
                            amount += product.price_discount * op.number
                        else:
                            return Response({'status': 3, 'detail': '商品%s价格已发生了变化，请重新下单' % product.title})
                    else:
                        return Response({'status': 4, 'detail': '商品%s已发生了变化，请重新下单' % op.title})
                else:
                    return Response({'status': 10, 'detail': '活动类型错误'})

        if not amount == order_amount:
            return Response({'status': 5, 'detail': '商品总价已发生了变化，请重新下单'})

        flag, result = wx_pay_prepare(order, order.shop_id, openid, amount, ip, 'kanjia')

        return Response({'status': flag, 'detail': result})


class WxPayForGroupShoppingView(APIView):
    """
    团购支付请求
    接收的数据类型为：
    {
        "order":订单号，
        "channel":渠道，APP/JSAPI
        "amount":总价
        "openid":微信openid
    }
    """
    permission_classes = (IsAuthenticated,)

    def post(self, request, *args, **kwargs):
        if not {'order', 'channel', 'amount', 'openid'}.issubset(request.data):
            return Response({'status': 1, 'detail': '参数错误'})

        order_id = request.data['order']
        channel = request.data.get('channel', 'APP')
        order_amount = transforms_int(request.data['amount'], 0)
        openid = request.data.get('openid', None)

        ip = request.META.get('REMOTE_ADDR', '127.0.0.1')

        order = get_obj(Order, id=order_id, user=request.user, state=Order.STATE_WAIT_PAY, status=Order.STATUS_VALID)
        if not order:
            return Response({'status': 2, 'detail': '待支付订单不存在'})

        if not hasattr(order.shop, 'public_shop'):  # 未设置 公众号_店铺 映射信息
            return Response({'status': 23, 'detail': '支付出错，店铺未设置公众号信息。'})

        # 判断商品价格
        order_product = get_obj(OrderProduct, order_id=order_id, status=OrderProduct.STATUS_VALID)
        if not order_product:
            return Response({'status': 3, 'detail': '待支付订单产品不存在'})

        product = order_product.content_object
        groupshopping_info = product.info
        if groupshopping_info.shelve is False:
            return Response({'status': 5, 'detail': '活动未上架'})

        if groupshopping_info.start_time > timezone.now():
            return Response({'status': 6, 'detail': '活动未开始'})
        if groupshopping_info.end_time < timezone.now():
            return Response({'status': 6, 'detail': '活动已截止'})

        if order.order_type == Order.ORDER_TUANSHOPPING_MASTER:
            if not groupshopping_info.get_inventory_status():
                return Response({'status': 7, 'detail': '活动名额已满'})

            try:
                member = ShoppingMem.objects.get(order=order, role=ShoppingMem.ROLE_MASTER, user=order.user,
                                                 info=groupshopping_info)
            except ShoppingMem.DoesNotExist:
                return Response({'status': 4, 'detail': '开团信息不存在'})

        elif order.order_type == Order.ORDER_TUANSHOPPING_GROUP:
            try:
                member = ShoppingMem.objects.get(order=order, role=ShoppingMem.ROLE_GROUPER, user=order.user,
                                                 info=groupshopping_info)
            except ShoppingMem.DoesNotExist:
                return Response({'status': 1, 'detail': '开团信息不存在'})

            if not member.group.group_state == ShoppingGroup.GROUP_DOING:
                return Response({'status': 12, 'detail': '拼团状态为%s' % member.group.get_group_state_display()})
        else:
            return Response({'status': 14, 'detail': '订单类型错误'})

        flag, result = wx_pay_prepare(order, order.shop_id, openid, order_amount, ip, 'groupshopping')

        return Response({'status': flag, 'detail': result})


def wx_pay_prepare(order, shop_id, openid, amount, ip, activity_type):
    """
    微信支付 初始化操作
    :param order: Order Instance
    :param shop_id:
    :param openid:
    :param amount: 支付金额
    :param ip: 请求IP
    :param activity_type: str 活动类型
    :return:
    """
    if order.pay_type == Order.SELF_PUB:
        pi = get_obj(WxPayInfo, app_id=order.shop.public_shop.app_id, status=WxPayInfo.STATUS_VALID)
    elif order.pay_type == Order.PAY_WX_SERVICE:
        pi = get_obj(WxPublicMapShop, shop_id=shop_id, status=WxPublicMapShop.STATUS_VALID)
    elif order.pay_type == Order.PAY_XIAODU:  # 小嘟科技的支付  特殊的SELF_PUB支付方式
        pi = get_obj(WxPayInfo, app_id='wx87433e29e621c32e', status=WxPayInfo.STATUS_VALID)
    else:
        return 1, '订单支付方式有误！'
    if not pi:
        return 1, '支付出错，系统未对接微信支付'
    if order.pay_type in [Order.SELF_PUB, Order.PAY_XIAODU]:  # 普通商户号支付
        config = WxPayConf_pub()
        config.APPID = pi.app_id
        config.MCHID = pi.mch_id
        config.KEY = pi.key
        config.SSLCERT_PATH = os.path.join(settings.BASE_DIR, settings.MEDIA_ROOT, '/%s.cert.pem' % pi.app_id)
        config.SSLKEY_PATH = os.path.join(settings.BASE_DIR, settings.MEDIA_ROOT, '/%s.key.pem' % pi.app_id)
        appApi = WxApi_pub()
        appApi.setConfig(config)
        unifiedOrder = UnifiedOrder_pub()
        unifiedOrder.setConfig(config)
        unifiedOrder.setParameter('openid', openid)
    elif order.pay_type == Order.PAY_WX_SERVICE:
        # 目前不适用， 后期用于替代线上的特约商户支付
        config = WxPayConf_service()
        appApi = WxApi_pub()
        appApi.setConfig(config)
        unifiedOrder = UnifiedOrder_pub()
        unifiedOrder.setConfig(config)
        unifiedOrder.setParameter('sub_appid', pi.app_id)
        unifiedOrder.setParameter('sub_mch_id', pi.mch_id)
        unifiedOrder.setParameter('openid', openid)
    else:
        return 1, '订单支付方式有误！'

    unifiedOrder.setParameter('body', order.shop.title + '支付')  # 商品描述
    unifiedOrder.setParameter('out_trade_no', order.id)  # 商户订单号
    unifiedOrder.setParameter('total_fee', str(amount))  # 总金额
    unifiedOrder.setParameter('spbill_create_ip', ip)  # 终端ip
    unifiedOrder.setParameter('notify_url', config.NOTIFY_URL)  # 通知地址
    unifiedOrder.setParameter('trade_type', 'JSAPI')  # 交易类型
    unifiedOrder.setParameter('attach', activity_type)  # 交易类型

    flag, result = unifiedOrder.getPrepayId()

    if flag:
        appApi.setPrepayId(result)
        if order.pay_type == Order.SELF_PUB:
            jsApiParameters = appApi.getParameters()
        else:
            jsApiParameters = appApi.getParameters(appid=pi.app_id)
        flag = 0
        result = {'params': jsApiParameters, 'order': order.id}
    else:
        flag = 15
        result = result['return_msg']
    return flag, result
